#include "printf.h"
#include "console.h"  

// 定义数字字符数组，用于数字到字符的转换
static char digits[] = "0123456789abcdef";

/**
 * 数字输出函数
 * @param num   要打印的数字
 * @param base  进制基数
 * @param sign  是否是有符号数（1表示有符号，0表示无符号）
 */
static void print_number(long long num, int base, int sign)
{
  char buf[20];
  int i;
  unsigned long long x;

  if(sign && (sign = (num < 0)))
    x = -num;
  else
    x = num;

  // 将数字转换为指定进制的字符串（逆序存储）
  i = 0;
  do {
    buf[i++] = digits[x % base];
  } while((x /= base) != 0);

  if(sign)
    buf[i++] = '-';
  
   // 逆序输出
  while(--i >= 0)
    console_putc(buf[i]);
}

/**
 * 格式化输出函数（类似标准库的printf）
 * @param fmt  格式字符串
 * @param ...  可变参数
 * @return     总是返回0
 */
int printf(char *fmt, ...)
{
  va_list ap;//可变参数列表
  int i, cx, c0 ; // c1, c2;// 循环变量和字符临时变量
  char *s;

  va_start(ap, fmt);// 初始化可变参数列表
  //遍历格式化字符串
  for(i = 0; (cx = fmt[i] & 0xff) != 0; i++){
    if(cx != '%'){
      console_putc(cx);
      continue;
    }
    i++;
    c0 = fmt[i+0] & 0xff;// 第一个格式字符
    //c1 = c2 = 0;
    // if(c0) c1 = fmt[i+1] & 0xff;// 第二个字符（如果有）
    // if(c1) c2 = fmt[i+2] & 0xff;// 第三个字符（如果有）
    if(c0 == 'd'){// 有符号十进制整数
      print_number(va_arg(ap, int), 10, 1);
    } else if(c0 == 'x'){// 十六进制无符号整数
      print_number(va_arg(ap, uint32), 16, 0);
    } else if(c0 == 'c'){// 字符
      console_putc(va_arg(ap, uint));
    } else if(c0 == 's'){// 字符串
      if((s = va_arg(ap, char*)) == 0)
        s = "(null)";// 处理空指针情况
      for(; *s; s++)
        console_putc(*s);
    } else if(c0 == '%'){
      console_putc('%');
    } else if(c0 == 0){
      break;
    } else {
      // 打印未知的%序列以引起注意
      console_putc('%');
      console_putc(c0);
    }
  }
  va_end(ap);

  return 0;
}

void printf_init(void)
{
    console_init();
    printf("Printf system initialized.\n");
}